<?php
use Base\AdminController;
use JetBrains\PhpStorm\NoReturn;

class SendCopyController extends AdminController
{
    protected string $table = 'approvals';

    protected string $model = "approval";

    #[NoReturn] public function init(): void
    {
        $this->routeWhiteLst = ['sendcopy@isread', 'sendcopy@edit'];
        parent::init();
    }

    /**
     * 抄送列表
     * @return void
     */
    #[NoReturn] public function indexAction(): void
    {
        try {
            if (Request::input("flow_id") !== null) {
                $this->where[] = ['flow_id','=',Request::input("flow_id")];
            }
            $sql = ApprovalModel::query()
                ->join("users","users.id","=","approvals.user_id")
                ->join("organizations","organizations.id","=","approvals.org_id")
                ->join("flows","flows.id","=","approvals.flow_id")
                ->join("approval_cc_records","approval_cc_records.approval_id","=","approvals.id")
                ->where("approval_cc_records.recipient_id",$this->member_id)
                ->with(["user"=>function ($query) {
                    $query->selectRaw("nickname,avatar")->orderBy("step_order","asc");
                }])
                ->selectRaw("ws_approvals.*,ws_users.nickname,ws_users.avatar,
                ws_organizations.title as org_name,ws_flows.title as flow_name")
                ->where($this->where)
                ->when($this->whereIn,function ($query,$value){
                    foreach ($value as $item) {
                        $query->whereIn($item[0], $item[1]);
                    }
                });
            if (Request::input("time")) {
                if (is_array(Request::input("time"))) {
                    $sql->whereBetween("created_at",Request::input("time"));
                }else {
                    $sql->whereDate("created_at",Request::input("time"));
                }
            }
            $data = $sql->orderBy("id","desc")
                ->paginate(Request::input("limit",10),['*'],NULL,Request::input("p",1));
            $res = collect($data->items())->toArray();
            foreach ($res as $key=>$vo) {
                $res[$key]['status_d'] = ApprovalModel::$statusMap[$vo['status']];
                $res[$key]['status_color']  = match ($vo['status'])
                {
                    0=>"primary",
                    1=>"success",
                    2=>"danger",
                    -1=>"info",
                    default => 'primary',
                };
                if ($vo['user']) {
                    $res[$key]['approved_by'] = implode(";", array_column($vo['user'], 'nickname'));
                }
                unset($res[$key]['user']);
            }
            $result = [
                'items' => $res,
                'total'=>$data->total(),
                'per_page' => $data->perPage(),
                'page' => $data->currentPage()
            ];
            $this->apiSuccess($result,"获取成功",20000);
        }catch (Exception $exception) {
            Log::$customFileName = LOG_PATH."/errors/";
            Log::error($exception->getMessage().$exception->getTraceAsString());
            $this->apiError($exception->getMessage());
        }
    }

    /**
     * 我处理的列表
     * @return void
     */
    #[NoReturn] public function tackleAction(): void
    {
        try {
            if (Request::input("flow_id") !== null) {
                $this->where[] = ['flow_id','=',Request::input("flow_id")];
            }
            $status  = match (Request::input("status"))
            {
                "pending"=>0,
                "success"=>1,
                default => '',
            };
            $sql = ApprovalModel::query()
                ->join("users","users.id","=","approvals.user_id")
                ->join("organizations","organizations.id","=","approvals.org_id")
                ->join("flows","flows.id","=","approvals.flow_id")
                ->join("approval_flows","approval_flows.approval_id","=","approvals.id")
                ->when($status,function ($query,$status) {
                    $query->where("approvals.status",$status);
                })
                ->where("approval_flows.approval_user_id",$this->member_id)
                ->with(["user"=>function ($query) {
                    $query->selectRaw("nickname,avatar")->orderBy("step_order","asc");
                }])
                ->selectRaw("ws_approvals.*,ws_users.nickname,ws_users.avatar,
                ws_organizations.title as org_name,ws_flows.title as flow_name,ws_approval_flows.step_order");
            if (Request::input("time")) {
                if (is_array(Request::input("time"))) {
                    $sql->whereBetween("created_at",Request::input("time"));
                }else {
                    $sql->whereDate("created_at",Request::input("time"));
                }
            }
            $data = $sql->orderBy("id","desc")
                ->paginate(Request::input("limit",10),['*'],NULL,Request::input("p",1));
            $res = collect($data->items())->toArray();
            foreach ($res as $key=>$vo) {
                $res[$key]['status_d'] = ApprovalModel::$statusMap[$vo['status']];
                $res[$key]['status_color']  = match ($vo['status'])
                {
                    0=>"primary",
                    1=>"success",
                    2=>"danger",
                    -1=>"info",
                    default => 'primary',
                };
                if ($vo['user']) {
                    $res[$key]['approved_by'] = implode(";", array_column($vo['user'], 'nickname'));
                }
                unset($res[$key]['user']);
            }
            $result = [
                'items' => $res,
                'total'=>$data->total(),
                'per_page' => $data->perPage(),
                'page' => $data->currentPage()
            ];
            $this->apiSuccess($result,"获取成功",20000);
        }catch (Exception $exception) {
            Log::$customFileName = LOG_PATH."/errors/";
            Log::error($exception->getMessage().$exception->getTraceAsString());
            $this->apiError($exception->getMessage());
        }
    }

    #[NoReturn] public function handleAction(): void
    {
        DB::beginTransaction();
        try {
            $approval = ApprovalModel::query()
                ->where("id", Request::input("id"))
                ->first();
            if ($approval['status'] >= 1) $this->apiError("该事项已处理，请勿重复操作");
            $flowProcess = FlowModel::query()->where("id", $approval['flow_id'])->first();
            $flow = ApprovalFlowModel::query()->where("approval_id", Request::input("id"))
                ->where("approval_user_id", $this->member_id)
                ->where("step_order", Request::input("step_order"))
                ->first();
            if ($flow['status'] >= 1) $this->apiError("该事项已处理，请勿重复操作");
            $mode = 2;
            foreach ($flowProcess['data']['flow'] as $vo) {
                if ($vo['level'] == Request::input("step_order")) {
                    $mode = $vo['mode'];
                }
            }
            ApprovalFlowModel::where("approval_id", Request::input("id"))
                ->where("approval_user_id", $this->member_id)
                ->where("step_order", Request::input("step_order"))->update([
                    "status" => Request::input("status"),
                    "approve_at" => date("Y-m-d H:i:s"),
                    "comment" => Request::input("comment"),
                ]);
            $status = 0;
            if ($mode==2) {
                $status = 1;
            }else {
                $step_num = ApprovalFlowModel::query()->where("approval_id", Request::input("id"))
                    ->where("type", 1)->where("status", "<=", 0)
                    ->count();
                if ($step_num == 0) {
                    //更新事项状态
                    $status = 1;
                }
            }
            if (Request::input("satus")==2) {
                $status = 2;
            }
            ApprovalModel::where("id", Request::input("id"))->update([
                "status" => $status,
            ]);
            if ($status >= 1) {
                //更新待办任务
                DoTaskModel::where("resource_id", Request::input("id"))->where("type", 2)->update([
                    "is_done" => 1,
                ]);
            }else {
                DoTaskModel::where("resource_id", Request::input("id"))
                    ->where("type", 2)->where("review_user_id",$this->member_id)->update([
                    "is_done" => 1,
                ]);
            }
            DB::commit();
            $this->apiSuccess([],"处理成功",20000);
        }catch (Exception $exception) {
            DB::rollBack();
            Log::$customFileName = LOG_PATH."/errors/";
            Log::error($exception->getMessage().$exception->getTraceAsString());
            $this->apiError($exception->getMessage());
        }
    }

    #[NoReturn] public function isReadAction(): void
    {
        DB::beginTransaction();
        try {
            $approval = ApprovalModel::query()
                ->where("id", Request::input("id"))
                ->first();
            if ($approval['status'] >= 1) $this->apiError("该事项已处理，请勿重复操作");
            $flow = ApprovalCcRecordModel::query()->where("approval_id", Request::input("id"))
                ->where("recipient_id", $this->member_id)
                ->first();
            if ($flow['status'] >= 1) $this->apiError("该事项已读，请勿重复操作");
            ApprovalCcRecordModel::where("approval_id", Request::input("id"))
                ->where("recipient_id", $this->member_id)
               ->update([
                    "status" => Request::input("status"),
                    "notified_at" => date("Y-m-d H:i:s"),
                ]);
            DB::commit();
            $this->apiSuccess([],"处理成功",20000);
        }catch (Exception $exception) {
            DB::rollBack();
            Log::$customFileName = LOG_PATH."/errors/";
            Log::error($exception->getMessage().$exception->getTraceAsString());
            $this->apiError($exception->getMessage());
        }
    }

    /**
     * 显示
     * @return void
     */
    #[NoReturn] protected function operate(): void
    {
        try {
            $info = ApprovalModel::query()
                ->join("users","users.id","=","approvals.user_id")
                ->join("organizations","organizations.id","=","approvals.org_id")
                ->join("flows","flows.id","=","approvals.flow_id")
                ->leftJoin("approval_cc_records",function ($query){
                    $query->on("approval_cc_records.approval_id","=","approvals.id")
                        ->where("approval_cc_records.recipient_id","=",$this->member_id);
                })
                ->leftJoin("approval_flows",function ($query){
                    $query->on("approval_flows.approval_id","=","approvals.id")
                        ->where("approval_flows.approval_user_id","=",$this->member_id);
                })
                ->where("approvals.id",Request::input("ids"))
                ->with(["user"=>function ($query) {
                    $query->selectRaw("nickname,avatar")->orderBy("step_order","asc");
                }])
                ->selectRaw("ws_approvals.*,ws_users.nickname,ws_users.avatar,
                ws_organizations.title as org_name,ws_flows.title as flow_name,ws_approval_flows.comment,
                ws_approval_flows.status as flow_status,ws_approval_flows.step_order")->first();
            if (!$info) $this->apiError("数据不存在");
            $info = $info->toArray();
            $info['status_d'] = ApprovalModel::$statusMap[$info['status']];
            $info['status_color']  = match ($info['status'])
            {
                0=>"primary",
                1=>"success",
                2=>"danger",
                -1=>"info",
                default => 'primary',
            };
            if ($info['user']) {
                $info['approved_by'] = implode(";", array_column($info['user'], 'nickname'));
            }
            $info['extra'] = json_decode($info['extra'],true);
            $exists = ApprovalCcRecordModel::query()
                ->where("approval_id",Request::input("ids"))
                ->where("recipient_id",$this->member_id)->where("status",0)->exists();
            if ($exists) {
                ApprovalCcRecordModel::where("approval_id",Request::input("ids"))
                    ->where("recipient_id",$this->member_id)
                    ->update(["status"=>1,"notified_at"=>date("Y-m-d H:i:s")]);
            }
            unset($info['user']);
            $this->apiSuccess($info,"获取成功",20000);
        }catch (Exception $exception) {
            Log::$customFileName = LOG_PATH."/errors/";
            Log::error($exception->getMessage().$exception->getTraceAsString());
            $this->apiError($exception->getMessage());
        }
    }
}
